package dk.aau.walkietalkie.network;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;

import android.annotation.SuppressLint;
import android.os.Environment;
import android.util.Base64;
import android.util.Log;
import android.widget.EditText;
import dk.aau.walkietalkieui.message.MyMessage;
import dk.aau.walkietalkieui.message.MyMessage.MessageType;

@SuppressLint("NewApi")
public class MessageSenderF {

	private static final int SENDER_PORT = 8988;
	private static final int RECEIVER_PORT = 8956;
	private ReceiverThread receiverThread = null;
	private ClientThread clientThread = null;
	// private ClientThread clientThread = new ClientThread();
	private EditText messageToBeSentEditText;
	private String ip;
	private MyMessage msg;
	private String Msg_String = null; 
	public boolean is_connected = false;
	
	private static final String FILE_PATH_IMAGE = Environment
			.getExternalStorageDirectory().getAbsolutePath() + "/tmp_image.jpg";
	
	private static final String FILE_PATH_AUDIO = Environment
			.getExternalStorageDirectory().getAbsolutePath() + "/tmp_audio.3pg";
	
	public boolean sendMessageViaNetwork (MyMessage msg) {
		this.msg = msg;
			try {
				clientThread = new ClientThread();
				clientThread.start();
				
				//sendEncodedMessage(msgEncode(msg));
				Msg_String = msgEncode(msg);
				sendEncodedMessage(Msg_String);
				Log.e("CONNECTED", "Envia caralho!!!!!!!");
				return true;
			} catch (Exception e) {
				Log.d("ERROR", "Msg de erro: " + e.getMessage());
			}
		//}
	return false;
	}
	
	private String msgEncode(MyMessage msg) {
		
		File file = new File(msg.getDataPath());
		MessageType msgType = msg.getType();
		

		switch (msgType) {
			case TYPE_RECORD: {
				FileInputStream AudioInFile = null;
				try{
				AudioInFile = new FileInputStream(file);
				
				byte AudioData[] = new byte[(int) file.length()];
            
				AudioInFile.read(AudioData);
				
				String AudioDataString = Base64.encodeToString(AudioData,Base64.DEFAULT);
			    AudioInFile.close();
			    return AudioDataString;
				}
				catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				}
				catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				break;
			}
			case TYPE_PICTURE: {
				
				FileInputStream imageInFile = null;
				try {
					imageInFile = new FileInputStream(file);
					
					byte imageData[] = new byte[(int) file.length()];
	            
					imageInFile.read(imageData);
					
					String imageDataString = Base64.encodeToString(imageData,Base64.DEFAULT);
				    imageInFile.close();
					return imageDataString;
				}
				catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				}
				catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

				/*
				ByteArrayOutputStream stream = new ByteArrayOutputStream();
				
				byte val [] = stream.toByteArray();
				String ba = Base64.encodeToString(val, Base64.DEFAULT);
				//return ba;*/
				break;
			}
			case TYPE_TEXT: {
				Log.e("CONNECTED", "Envia  TXT caralho!!!!!!!");
				String Txt_string = msg.getDataPath();
				return Txt_string; 
			}
			
		}
		Log.e("CONNECTED","Null caralho !!!!!");
		return null;
		
	}
	
	private void sendEncodedMessage(String encodedMsg) {
		OutputStream os = clientThread.getOutputStream();
		
		try {
			if (os != null) {
				Log.e("CONNECTED","->_>_>_>_>_>_>__>");		
				os.write(msg.getTCPMessage(encodedMsg).getBytes());
				os.flush();
				Log.e("CONNECTED","----------------");			
			} else {
				Log.e("CONNECTED", "Socket is closed !!!!");
			}
		} catch (Exception e) {
			Log.e("CONNECTED", "Msg de erro: " + e.getMessage());
		}
		finally {
			try {
				
				os.close();
				Log.e("CONNECTED","scoket Close !!!!!");
				clientThread.disconnect();
				clientThread.stop();
			} catch (Exception e) {

			}
		}	
	}
	
	public class ClientThread extends Thread {
		
		private Socket socket;
		public OutputStream os = null;;
		private String destination;
		
		@Override
		public void run() {
			try {
				//destination = "192.168.43.134";
				destination = msg.getDestinyIp(); // force this IP
				socket = new Socket(destination, SENDER_PORT);
				os = socket.getOutputStream();
				if (os == null)
					Log.e("CONNECTED","CARALHO os null !!!!");
				
				Log.e("CONNECTED", "Connected to " );

			} catch (UnknownHostException e) {		
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}	
	}

	public OutputStream getOutputStream() {

	return this.os;
	}
	
	public void disconnect() {
		try {
			if (socket != null) {
				socket.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		socket = null;
	}
  }
	
  public class ReceiverThread extends Thread {

		private static final int DEFAULT = 0;

		private boolean isRunning = false;

		private ServerSocket socketR;

		private BufferedReader entry;

		private DataOutputStream output;

		private String msgReceive_aux = null;

		private String msgReceive = " ";
		
		@Override
		public void run() {
			
			isRunning = true;
			socketR = null;

			try {
				Socket SocketReader = null;

				socketR = new ServerSocket(SENDER_PORT);
				while (isRunning) {
					SocketReader = socketR.accept();

					entry = new BufferedReader(new InputStreamReader(
							SocketReader.getInputStream()));

					// output = new
					// DataOutputStream(SocketReader.getOutputStream());

					msgReceive_aux = entry.readLine();

					while (msgReceive_aux != null) {
						msgReceive.concat(msgReceive_aux);
						msgReceive_aux = entry.readLine();
					}
					entry.close();
					msgReceive_aux = null;

					receivedMessageType(msgReceive);

					msgReceive = " ";

				}

			} catch (UnknownHostException e) {
				// isConnected = false;
				e.printStackTrace();
			} catch (IOException e) {
				// isConnected = false;
				e.printStackTrace();
			}
		}
		private Object receivedMessageType(String msgReceive) {

			char[] aux = null;
			String IpSender;
			String NameSender;
			String IpReceiver;
			String NameReceiver;
			int Type;
			String Data;
			
			Object screen = null;

			if (msgReceive != null) {
				// handle Ipsender
				msgReceive.getChars(
						msgReceive.indexOf("IdentificationSender: ") + 22,
						msgReceive.indexOf("/#/") - 1, aux, 0);
				IpSender = new String(aux);
				aux = null;

				// handle Namesender
				msgReceive.getChars(msgReceive.indexOf("/#/") + 3,
						msgReceive.indexOf("||") - 1, aux, 0);
				NameSender = new String(aux);
				aux = null;
				Log.d("SENDER", " " + IpSender + " -> " + NameSender);
				
				// handle IpReceiver
				msgReceive.getChars(
						msgReceive.indexOf("IdentificationDestiny: ") + 24,
						msgReceive.indexOf("//#//") - 1, aux, 0);
				IpReceiver = new String(aux);
				aux = null;

				// handle NameReceiver
				msgReceive.getChars(msgReceive.indexOf("//#//") + 5,
						msgReceive.indexOf("|||") - 1, aux, 0);
				NameReceiver = new String(aux);
				aux = null;
				Log.d("RECEIVER", " " + IpReceiver + " -> " + NameReceiver);

				// handle type
				msgReceive.getChars(msgReceive.indexOf("Type: ") + 6,
						msgReceive.indexOf("||||") - 1, aux, 0);
				Type = Integer.parseInt(new String(aux));
				aux = null;
				Log.d("TYPE", " " + Type);

				// handle data
				//TODO How is the data stocked ? Is the recorded file in a string ?
				msgReceive.getChars(msgReceive.indexOf("Data: ") + 6,
						msgReceive.indexOf(" END###!!!") - 1, aux, 0);
				Data = new String(aux);
				aux = null;

				Log.e("DATA", "data-> " + Data + " ");
				
				screen = convertToType(Data, Type);
				
				if (screen == null){
					Log.e("RECEIVING", "Msg not received !!!!");
					return null;
				}
				if (screen.getClass().equals(String.class)){
					Log.e("RECEIVING", "String msg received !!!!");
					return (String) screen;
				}
				if (screen.getClass().equals(File.class)){
					Log.e("RECEIVING", "String msg received !!!!");
					return screen.toString();
				}
				 

			} else {
				Log.e("CONNECT", "Error Receiving data!!!");
				return null;

			}
		return null;
		}
		@SuppressLint("NewApi")
		public Object convertToType(String Data, int Type) {
			byte[] image_byte = null;
			byte[] audio_byte = null;

			if (Type == MyMessage.MessageType.TYPE_RECORD.ordinal()) {
				audio_byte = Base64.decode(Data, Base64.DEFAULT);
				try{
				FileOutputStream audioOutFile = new FileOutputStream(
						FILE_PATH_AUDIO);
	            audioOutFile.write(image_byte);
	     
	            audioOutFile.close();
	            Log.e("AUDIO", "New msg received !!!!");
	            
	            return audioOutFile;
				}catch(Exception e){
					
				}
				Log.d("AUDIO", "New msg not received !!!!");
				return null;
			}

			if (Type == MyMessage.MessageType.TYPE_PICTURE.ordinal()) {
				image_byte = Base64.decode(Data, Base64.DEFAULT);
				try{
				FileOutputStream imageOutFile = new FileOutputStream(
						FILE_PATH_IMAGE);
	            imageOutFile.write(image_byte);
	     
	            imageOutFile.close();
	            Log.e("IMAGE", "New msg received !!!!");
	            
	            return imageOutFile;
	            
				}catch(Exception e){
					
				}
				
				//image_byte = Base64.decode(Data, Base64.DEFAULT);
				//Bitmap decodedByte = BitmapFactory.decodeByteArray(image_byte, 0, image_byte.length);
				//String path = Environment.getExternalStorageDirectory().toString();
				//OutputStream fOut = null;
				//File file = new File(path,"ReceivedPicture"+".jpg");
				//fOut = new FileOutputStream(file);
				//MediaStore.Images.Media.insertImage(getContentResolver(), file.getAbsolutePath(), file.getName(), file.getName());				
				
				Log.d("IMAGE", "New msg not received !!!!");
				return null;
			}

			if (Type == MyMessage.MessageType.TYPE_TEXT.ordinal()) {
				Log.e("TXT", "New msg received !!!!");
				return Data;
			}
			return null;
		}
		
  }

}
